/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package SearchEngineQuery;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import ApacheClient.ApacheClient;
import Parser.ParseTree;
import Parser.Token;

/**
 *
 * @author Chris
 */
public class GoogleQuery {
    private ApacheClient client = new ApacheClient();
    private int queryDelay = 0;
    private int pageDelay = 0;
    private int pDelayRange = 0;
    private int qDelayRange = 0;

    public GoogleQuery() {

    }

    public GoogleQuery(int queryDelay, int pageDelay) {
        this.queryDelay = queryDelay;
        this.pageDelay = pageDelay;
    }

    public GoogleQuery(int queryDelay, int pageDelay, int qDR, int pDR) {
        this.queryDelay = queryDelay;
        this.pageDelay = pageDelay;
        qDelayRange = qDR;
        pDelayRange = pDR;
    }

    protected void pageDelay() throws Exception {
        // A pointless delay
        Thread.sleep(pageDelay + (int) (Math.random() * pDelayRange));
    }

    protected void queryDelay() throws Exception {
        // A pointless delay
        Thread.sleep(queryDelay + (int) (Math.random() * qDelayRange));
    }

    // Replace unacceptable entries with valid ones
    protected String fixQuery(String query) {
        String result;

        result = query;
        result = result.replace(" ", "+");
        result = result.replace("%", "%25");

        return result;
    }

    public InputStream submitQuery(String query, int page) throws IOException {
        String prefix = "http://www.google.com/search?hl=en&q=";
    	//String prefix = "http://www.bing.com/search?q=";
    	String suffix = "";
        String urltext;

        query = fixQuery(query);

        if (page <= 1)
            urltext = prefix + query + suffix;
        else
           urltext = prefix + query + "&start=" + ((page - 1) * 10) + "&sa=N" + suffix;
        	//urltext = prefix + query + "&go=&qs=n&sk=&sc=8-11&first=" + (((page-1)*10) + 1) + suffix;
       //System.out.println (urltext);
        return client.getPage(urltext);
    }

    public ArrayList<SearchResult> getResults(String query, int page) throws Exception {
        ArrayList<SearchResult> result = new ArrayList<SearchResult>();
        InputStream content = submitQuery(query, page);
        BufferedReader read = new BufferedReader(new InputStreamReader(content));
        ParseTree tree = new ParseTree(read);
        Token[] tokens = tree.getTokens();
        int pos;
        int pos2;
        int pos3;

        String url;
        String summary;
        String att;

        // Get the <a ...> tags
        pos = tree.findNextTag(0, Token.A);
        while (pos >= 0) {
            att = tokens[pos].valueOfAtt("class");
            if (att != null && att.equalsIgnoreCase("l")) {
            	System.out.println(tokens[pos].valueOfAtt("href"));
                url = tokens[pos].valueOfAtt("href");
                pos2 = tree.findNextTag(pos + 1, Token.DIV);
                pos3 = tree.findNextTag(pos2 + 1, Token.SPAN);
                summary = tree.getAllText(pos2, pos3).toString();
                //summary = tree.getAllTextInsideToken(pos2).toString();
                if (!url.startsWith("http://www.youtube.com")) {
                    result.add(new SearchResult(url, summary));
                }
               // System.out.println(url);
            }
            pos = tree.findNextTag(pos + 1, Token.A);
          
        }

        read.close();

        return result;
    }

    public ArrayList<SearchResult> getResults(String query, int startPage, int endPage) throws Exception {
        ArrayList<SearchResult> result = new ArrayList<SearchResult>();

        for (int c = startPage; c <= endPage; c++) {
            result.addAll(getResults(query, c));
        }

        return result;
    }

    public ArrayList<SearchResult> getResultsWithDelay(String query, int startPage, int endPage) throws Exception {
        ArrayList<SearchResult> result = new ArrayList<SearchResult>();

        for (int c = startPage; c <= endPage; c++) {
            result.addAll(getResults(query, c));
            pageDelay();
        }

        return result;
    }
}
